package com.tnovoselec.android.travelassistant.overlay;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.net.Uri;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.MapView.LayoutParams;
import com.google.android.maps.OverlayItem;
import com.tnovoselec.android.lbs.location.MyLocationService;
import com.tnovoselec.android.travelassistant.R;
import com.tnovoselec.android.travelassistant.dto.IGeoPoint;
import com.tnovoselec.android.travelassistant.view.CustomMapView;

public abstract class AbstractMapOverlay<T extends IGeoPoint> extends ItemizedOverlay<OverlayItem> implements OnClickListener {

	protected Context mContext;

	protected int lastTappedItem = -1;
	protected ArrayList<OverlayItem> overlayItems;
	protected List<IGeoPoint> items;
	protected CustomMapView mapview;
	protected View popupView;

	protected static final Criteria CRITERIA = new Criteria();
	static {
		CRITERIA.setAccuracy(Criteria.ACCURACY_COARSE);
		CRITERIA.setAltitudeRequired(false);
		CRITERIA.setBearingRequired(false);
		CRITERIA.setCostAllowed(true);
		CRITERIA.setSpeedRequired(false);
		CRITERIA.setPowerRequirement(Criteria.NO_REQUIREMENT);
	}

	public AbstractMapOverlay(Drawable arg0) {
		super(arg0);
	}

	@Override
	protected OverlayItem createItem(int i) {

		return overlayItems.get(i);
	}

	@Override
	public int size() {
		return (items != null) ? items.size() : 0;
	}

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, false);
	}

	public void adjustMapViewToPOIs(CustomMapView mapView, GeoPoint geoPoint) {
		if (items.size() > 0) {
			float minLat = 90;
			float maxLat = -90;
			float minLng = 180;
			float maxLng = -180;

			for (IGeoPoint item : items) {
				if (item.getLatitude() < minLat) {
					minLat = item.getLatitude();
				}
				if (item.getLatitude() > maxLat) {
					maxLat = item.getLatitude();
				}
				if (item.getLongitude() < minLng) {
					minLng = item.getLongitude();
				}
				if (item.getLongitude() > maxLng) {
					maxLng = item.getLongitude();
				}
			}
			if (geoPoint != null) {
				if (geoPoint.getLatitudeE6() < minLat * 1e6) {
					minLat = (float) (geoPoint.getLatitudeE6() / 1E6);
				}
				if (geoPoint.getLatitudeE6() > maxLat * 1e6) {
					maxLat = (float) (geoPoint.getLatitudeE6() / 1E6);
				}
				if (geoPoint.getLatitudeE6() < minLng * 1e6) {
					minLng = (float) (geoPoint.getLongitudeE6() / 1E6);
				}
				if (geoPoint.getLatitudeE6() > maxLng * 1e6) {
					maxLng = (float) (geoPoint.getLongitudeE6() / 1E6);
				}
			}

			mapView.animateTo(new GeoPoint((int) ((minLat + maxLat) / 2 * 1E6), (int) ((minLng + maxLng) / 2 * 1E6)));
			mapView.zoomToSpan((int) ((maxLat - minLat) * 1E6), (int) ((maxLng - minLng) * 1E6));
		}
	}

	public void handleListClick(IGeoPoint item) {
		for (int i = 0; i < items.size(); i++) {
			if (items.get(i).getPoi_id().equals(item.getPoi_id())) {
				onTap(i);
				return;
			}
		}
	}

	@Override
	public boolean onTap(GeoPoint p, MapView mapView) {
		final boolean itemTap = super.onTap(p, mapView);
		if (!itemTap) {
			mapview.removeAllViews();
			lastTappedItem = -1;
			return true;
		}

		return itemTap;
	}

	@Override
	protected boolean onTap(int index) {
		lastTappedItem = index;
		final IGeoPoint item = items.get(index);

		final LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, item.getGeoPoint(), LayoutParams.BOTTOM_CENTER);

		mapview.removeAllViews();
		mapview.addView(popupView, params);

		final TextView title = (TextView) popupView.findViewById(R.id.balloon_item_title);
		title.setText(getItem(index).getTitle());

		final TextView snippet = (TextView) popupView.findViewById(R.id.balloon_item_snippet);
		snippet.setText(getItem(index).getSnippet());

		mapview.disableOnMoveListener();
		mapview.animateTo(item.getGeoPoint());

		return true;
	}

	@Override
	public void onClick(View v) {
		if (v == popupView) {
			GeoPoint myLoc = MyLocationService.getLastKnownGeoPoint(mContext, CRITERIA);
			float fromLat = (float) (myLoc.getLatitudeE6() / 1e6);
			float fromLng = (float) (myLoc.getLongitudeE6() / 1e6);
			float toLat = items.get(lastTappedItem).getLatitude();
			float toLng = items.get(lastTappedItem).getLongitude();
			Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?saddr=" + fromLat + "," + fromLng + "&daddr="
					+ toLat + "," + toLng + ""));
			if (mContext != null) {
				mContext.startActivity(intent);
			}
		}

	}

	public void hidePopup() {
		mapview.removeAllViews();
	}
}
